/*
 * *******************************************************************
 *   @项目名称: BHex Android
 *   @文件名称: APPConfig.java
 *   @Date: 18-11-29 下午4:05
 *   @Author: ppzhao
 *   @Description:
 *   @Copyright（C）: 2018 BlueHelix Inc.   All rights reserved.
 *   注意：本内容仅限于内部传阅，禁止外泄以及用于其他的商业目的.
 *  *******************************************************************
 */

package io.bhex.app.app;

import android.app.Activity;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.datatheorem.android.trustkit.TrustKit;
import com.datatheorem.android.trustkit.reporting.BackgroundReporter;
import com.geetest.deepknow.DPAPI;
import com.tencent.mmkv.MMKV;
import com.umeng.analytics.MobclickAgent;
import com.umeng.commonsdk.UMConfigure;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import io.bhex.app.BuildConfig;
import io.bhex.app.R;
import io.bhex.app.broadcast.receiver.PinningFailureReportBroadcastReceiver;
import io.bhex.app.utils.CommonUtil;
import io.bhex.app.utils.CustomerServiceUtils;
import io.bhex.app.utils.DialogUtils;
import io.bhex.app.utils.IntentUtils;
import io.bhex.app.utils.NetWorkStatus;
import io.bhex.app.utils.ShareConfigUtils;
import io.bhex.baselib.constant.Fields;
import io.bhex.baselib.core.AsyncTask;
import io.bhex.baselib.core.CApplication;
import io.bhex.baselib.network.CodeCheckInterceptor;
import io.bhex.baselib.network.Encode;
import io.bhex.baselib.network.HttpUtils;
import io.bhex.baselib.network.JsonLevelChangeInterceptor;
import io.bhex.baselib.network.cookie.persistentcookiejar.persistence.SharedPrefsCookiePersistor;
import io.bhex.baselib.network.interceptor.BasicParamsInterceptor;
import io.bhex.baselib.network.listener.SimpleResponseListener;
import io.bhex.baselib.network.params.UploadParam;
import io.bhex.baselib.utils.DebugLog;
import io.bhex.baselib.utils.DevicesUtil;
import io.bhex.baselib.utils.JsonConvertor;
import io.bhex.baselib.utils.SignUtils;
import io.bhex.baselib.utils.StringUtils;
import io.bhex.baselib.utils.ToastUtils;
import io.bhex.sdk.BhexSdk;
import io.bhex.sdk.Config;
import io.bhex.sdk.UrlsConfig;
import io.bhex.sdk.config.ConfigApi;
import io.bhex.sdk.config.bean.BackupDomainList;
import io.bhex.sdk.config.bean.ShareConfigBean;
import io.bhex.sdk.data_manager.MMKVManager;
import io.bhex.sdk.data_manager.RateAndLocalManager;
import io.bhex.sdk.data_manager.UploadNetRequestManager;
import okhttp3.Cookie;

import static io.bhex.app.BuildConfig.PUSH_APP_KEY;


/**
 * APP初始化过程中进行参数配置
 */
public class APPConfig {

    private static final int NO_LOGIN_NOTIFY = 0x13;

    private Handler uiHandler = new Handler(Looper.getMainLooper()){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case NO_LOGIN_NOTIFY:
//                    String noLoginMsg = (String) msg.obj;
//                    showNoLoginNotify(noLoginMsg);
                    break;
            }
        }
    };

    private static APPConfig _instance;

    public static APPConfig getInstance() {
        if(_instance == null)
            _instance  = new APPConfig();
        return _instance;
    }

    private APPConfig() {

    }

    /**
     * 初始化配置
     */
    public void initConfig(){
        DebugLog.d("init");
        //同步
        //Debug.startMethodTracing("");
        //long t1 = SystemClock.currentThreadTimeMillis();
        syncInit();
        //Debug.stopMethodTracing();
        //long t2 = SystemClock.currentThreadTimeMillis();
        //Log.d("AppConfig:","同步 用时:"+(t2-t1));

        //异步
        AsyncTask.THREAD_POOL_EXECUTOR.execute(()->{
            aSyncInit();
        });
    }

    /**
     * 同步初始化
     */
    private void syncInit() {
        MMKV.initialize(BHexApplication.getInstance());
        //TODO 禁止调整下面 initCommomParams() 和 initBaseLibConfig()调用顺序
        //初始化公共参数
        initCommomParams(); /** 初始化参数要前置 **/
        // baseLib初始化
        initBaseLibConfig();

        loadHttpConfigParams();

        //设置打印日志开关
        DebugLog.setDebuggable(BuildConfig.DEBUG);

        MMKVManager.getInstance().loadKind_T_Tag();

        //预加载启动图
        preLoadLauchBg("");
//        preLoadLauchBg("https://static.bhfastime.com/bhop/image/NA6eIkv7Ohc-4ucUpqY9V-UTbSBXlnEStZhFL_83A18.png");
        //换肤
        SkinManager.getInstance().initConfig();
        //bugly崩溃统计
//        initBugly();
        //友盟
        APPConfig.getInstance().initUmengShare();
        //极验
        APPConfig.getInstance().initDeepKnow();

    }

    /**
     * 初始化公共参数
     */
    public void initCommomParams(){
        DevicesUtil.initDevicesParams(BHexApplication.getInstance());
    }

    /**
     * 加载http配置参数  header以及cookies
     */
    private void loadHttpConfigParams() {
        BasicParamsInterceptor.Builder builder = new BasicParamsInterceptor.Builder();

        Map<String, String> deviceParams = DevicesUtil.getDeviceParams();
        addParams(BHexApplication.getInstance(),deviceParams);

        Iterator<String> keyIterator = deviceParams.keySet().iterator();

        while (keyIterator.hasNext()) {
            String key = keyIterator.next();

            builder.addHeaderParam(key, Encode.urlEncode(StringUtils.replaceSpace(deviceParams.get(key))));
        }

        //添加post公共请求参数  Constants.PACKAGE 和 Constants.CFROM
        BasicParamsInterceptor basicParamsInterceptor = builder.build();
        HttpUtils.getInstance().addInterceptor(basicParamsInterceptor);
        //添加对于全局错误代码的统一拦截处理
        HttpUtils.getInstance().addInterceptor(new CodeCheckInterceptor(new CodeCheckInterceptor.CodeCheckListener(){

            @Override
            public void noLoginNotify(String msg) {
                Message message = new Message();
                message.what = NO_LOGIN_NOTIFY;
                message.obj = msg;
                uiHandler.sendMessage(message);
            }
        }));
        //HttpUtils.getInstance().addInterceptor(new );
        //对于网络请求进行初始化设置，添加Json解析器
        HttpUtils.getInstance().addInterceptor(new JsonLevelChangeInterceptor());  //次数不需要返回数据重新处理
        SharedPrefsCookiePersistor cookiePersistor =  new SharedPrefsCookiePersistor(CApplication.getInstance());
        List<Cookie> cookies = null;

        if(cookiePersistor != null){
            cookies = cookiePersistor.loadAll();
        }

        if (cookies != null && !cookies.isEmpty()) {
//            CookieUtils.setCookies(BHexApplication.getInstance(), cookies);
        }
        //对网路哟请求进行记录
        //HttpUtils.getInstance().addInterceptor(new LogginInterceptor());

    }

    /**
     *zendesk客服初始化
     */
    public void initZendesk(){
        CustomerServiceUtils.initZendesk(BHexApplication.getInstance());
        CustomerServiceUtils.setZendeskIdentify(BHexApplication.getInstance());
        CustomerServiceUtils.initZendeskSupport();
        CustomerServiceUtils.initZendeskChat();
    }

    /**
     * 增加公共参数
     * @param application
     * @param deviceParams
     */
    private void addParams(BHexApplication application, Map<String, String> deviceParams) {
        deviceParams.put(Fields.PARAM_CHANNEL, CommonUtil.getChannel(application));
        deviceParams.put(Fields.PARAM_APPID, CommonUtil.getPackageName(application));
    }

    /**
     * 未登录（登录踢出）提醒
     * @param msg
     */
    private void showNoLoginNotify(String msg) {
        final Activity currentActivity = ActivityManager.getInstance().getCurrentActivity();
        if (currentActivity != null) {
            DialogUtils.showDialog(currentActivity, currentActivity.getResources().getString(R.string.string_reminder), msg, currentActivity.getResources().getString(R.string.string_login), currentActivity.getResources().getString(R.string.string_version_cancel), false, new DialogUtils.OnButtonEventListener() {
                @Override
                public void onConfirm() {
                    IntentUtils.goLogin(currentActivity,"");
                }

                @Override
                public void onCancel() {

                }
            });
        }
    }

    /**
     * 初始化友盟的社会化分享
     */
    public void initUmengShare() {
        //友盟渠道统计
        if(!BuildConfig.DEBUG){
            UMConfigure.init(BHexApplication.getInstance(), BuildConfig.UMENG_APP_KEY, CommonUtil.getChannel(BHexApplication.getInstance()), UMConfigure.DEVICE_TYPE_PHONE, PUSH_APP_KEY);
        }

    }

    /**
     * 初始化深知
     */
    public void initDeepKnow() {
        try {
            DPAPI.getInstance(BHexApplication.getInstance(),null);
        }
        catch (Exception e){
        }
    }

    /**
     * 异步初始化
     */
    private void aSyncInit() {

        initNetworkSecurityConfig();

//        dnsParse();
        doDeviceActive();

        catchAppCrash();

        //内存分析
        memeryAnalysis();
        //
        ToastUtils.Init();
        //上传错误请求日志
        uploadRequestErrorListener();

        //查询商品相关信息
//        ProductProvider.getInstance().init();

        getShareConfig();

    }

    /**
     * 预加载启动图
     */
    private void preLoadLauchBg(String launchBgUrl) {
//        String launchBgUrl = "https://static.bhfastime.com/bhop/image/NA6eIkv7Ohc-4ucUpqY9V-UTbSBXlnEStZhFL_83A18.png";   //测试图片地址
        if (!TextUtils.isEmpty(launchBgUrl)) {
            Glide.with(BHexApplication.getInstance())
                    .load(launchBgUrl)
                    .downloadOnly(new SimpleTarget<File>() {
                        @Override
                        public void onResourceReady(File resource, GlideAnimation<? super File> glideAnimation) {
                            if (resource != null) {
                                if (resource.exists()) {
                                    String lauchFilePath = resource.getPath();
                                    if (!TextUtils.isEmpty(lauchFilePath)) {
                                        String currentLngCode = RateAndLocalManager.GetInstance(BHexApplication.getInstance()).getCurLocalKind().code;
                                        MMKVManager.getInstance().mmkv().encode("launch_bg_file_path_"+currentLngCode,lauchFilePath);
                                    }
                                }
                            }
                        }
                    });
        }


    }

    /**
     * DNS解析
     */
    private void dnsParse() {
//        Map<String, String> params = new HashMap<>();
//        params.put("dn", "app.bhex.io");
//
//        VolleyUtil.getJsonObject(BHexApplication.getInstance(), "http://119.29.29.29/d", params,
//                new Response.Listener<JSONObject>() {
//                    @Override
//                    public void onResponse(JSONObject s) {
//                        DebugLog.e(s.toString());
//
//                    }
//                },
//                new Response.ErrorListener() {
//                    @Override
//                    public void onErrorResponse(VolleyError volleyError) {
//
//                    }
//                });
    }

    /**
     * 设备激活
     */
    private void doDeviceActive() {
//        GetParams.Builder builder = GParamsBuilder.get()
//                .url(Urls.URL_DO_DEVICES_ACTIVE)
//                .addParam(Fields.FIELD_SID, sid)
//                .addParam(Fields.FIELD_APPKEY, Fields.FIELD_APPTYPE_DEFAULT_VALUE);
//
//        HttpUtils.getInstance().request(builder.build(), null, null);
    }

    public Handler getUiHandler() {
        return uiHandler;
    }

    /**
     * 获取分享配置
     */
    private void getShareConfig() {
        ConfigApi.getShareConfig(new SimpleResponseListener<ShareConfigBean>(){

            @Override
            public void onSuccess(ShareConfigBean response) {
                super.onSuccess(response);
            }

            @Override
            public void onError(Throwable error) {
                super.onError(error);
            }

            @Override
            public ShareConfigBean parserResponse(Handler uiHandler, String response, Class<ShareConfigBean> clazz) {
                if (!TextUtils.isEmpty(response)) {
                    ShareConfigUtils.saveShareConfigData(response);
                }
                return super.parserResponse(uiHandler, response, clazz);
            }
        });
    }

    /**
     * 初始化网络安全配置
     */
    private void initNetworkSecurityConfig() {
        if (CommonUtil.isBhex(BHexApplication.getInstance())) {
            TrustKit.initializeWithNetworkSecurityConfiguration(BHexApplication.getInstance());
            //Optionally add a local broadcast receiver to receive PinningFailureReports
            PinningFailureReportBroadcastReceiver receiver = new PinningFailureReportBroadcastReceiver();
            LocalBroadcastManager.getInstance(BHexApplication.getInstance())
                    .registerReceiver(receiver, new IntentFilter(BackgroundReporter.REPORT_VALIDATION_EVENT));

        }
    }

    /**
     * APP全局异常捕获 （只有release才进行捕获）
     */
    private void catchAppCrash() {
        if (!BuildConfig.DEBUG) {
            CrashHandler.install((thread, throwable) -> {

            });
        }
    }

    /**
     * baseLib初始化
     */
    private void initBaseLibConfig() {
        Config config = new Config();
        config.setOnlyDomain(BuildConfig.DOMAIN);
        config.setOrdId(BuildConfig.ORG_ID);
        config.setOnlyDomain(BuildConfig.DOMAIN);
        config.setDomainsKey(BuildConfig.BACKUP_DOMAIN_DECRYPT_KEY);
        config.setDomainReqUrl(BuildConfig.BACKUP_DOMAIN_REQ_URL);
        if (!TextUtils.isEmpty(BuildConfig.BACKUP_DOMAIN_LIST)) {
            try {
                String backupDomainListJson = SignUtils.decryptDataWithAES(config.getOrdId()+"."+config.getDomainsKey(), BuildConfig.BACKUP_DOMAIN_LIST);
                BackupDomainList backupDomains = JsonConvertor.getInstance().fromJson(backupDomainListJson, BackupDomainList.class);
                if (backupDomains != null) {
                    config.setDomainList(backupDomains);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        BhexSdk.InitConfig(BHexApplication.getInstance(), config,CommonUtil.isBhex(BHexApplication.getInstance()));
    }

    /**
     * 内存分析
     */
    private void memeryAnalysis() {
        //debug模式，进行leakcanary分析
        if (BuildConfig.DEBUG) {
//            LeakCanary.install(this);
        }
    }


    /**
     * 上传错误请求日志
     */
    private void uploadRequestErrorListener() {

        if (!BuildConfig.DEBUG) {
            //日志上报（release环境）
            BhexSdk.SetUploadResponseErrorListener(new BhexSdk.OnResponseErrorListener() {

                @Override
                public void OnUploadResponseError(String url, String errorCode) {

                    if(NetWorkStatus.isConnected(BHexApplication.getInstance())) {
                        try {
                            HashMap<String, String> map = new HashMap<String, String>();
                            String urlRequest = url;
                            if(url.contains("?") == true) {
                                urlRequest = url.substring(0, url.indexOf("?"));
                            }
                            String errorMsg = urlRequest + "";
                            if (!TextUtils.isEmpty(errorCode))
                                errorMsg = errorMsg + "__code + " + errorCode;
                            map.put("ResponseError", errorMsg);

                            String domain = UrlsConfig.API_SERVER_URL;
                            domain = domain.replace(':', '_');
                            domain = domain.substring(domain.indexOf("//") + 2, domain.lastIndexOf("/"));
                            MobclickAgent.onEvent(BHexApplication.getInstance(), domain + "_ResponseError", map);
                        }
                        catch (Exception e){

                        }
                    }

                }

                @Override
                public void OnUploadNetRequest(UploadParam param) {
                    UploadNetRequestManager.GetInstance().SetUploadRequestParam(param);
                }
            });
        }
    }

    /**
     * 初始化bugly崩溃统计
     */
    private void initBugly() {
        //bugly崩溃统计
//        BHexApplication application = BHexApplication.getInstance();
//        String packageName = application.getPackageName();
//        // 获取当前进程名
//        String processName = getProcessName(android.os.Process.myPid());
//        // 设置是否为上报进程
//        CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(application);
//        strategy.setUploadProcess(processName == null || processName.equals(packageName));
//       if (!BuildConfig.DEBUG) {
//            CrashReport.initCrashReport(BHexApplication.getInstance(), BuildConfig.BUGLY_APP_KEY, BuildConfig.DEBUG,strategy);
//        }
    }

    /**
     * 获取进程号对应的进程名
     *
     * @param pid 进程号
     * @return 进程名
     */
    private static String getProcessName(int pid) {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader("/proc/" + pid + "/cmdline"));
            String processName = reader.readLine();
            if (!TextUtils.isEmpty(processName)) {
                processName = processName.trim();
            }
            return processName;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException exception) {
                exception.printStackTrace();
            }
        }
        return null;
    }

}
